package com.wl.common.core.exception;


import com.wl.common.core.enums.ErrorCode;

import java.io.PrintWriter;
import java.io.StringWriter;

/**
 * @author: wanglin
 * @date: 2023-07-12 周三
 * @Version: 1.0
 * @Description:
 */
public class CustomException extends RuntimeException {
    private static final long serialVersionUID = -4138013499105708265L;

    private Integer code;
    private ErrorCode errorCode = ErrorCode.UNKNOWN;
    private CustomErrorCode customErrorCode;

    public CustomException() {
    }

    public CustomException(String msg) {
        super(msg);
    }

    public CustomException(Integer code, String msg) {
        super(msg);
        this.code = code;
    }

    public CustomException(ErrorCode errorCode, String msg) {
        super(errorCode.toString() + " - " + msg);
        this.errorCode = errorCode;
    }

    public CustomException(CustomErrorCode customErrorCode, String msg) {
        super(customErrorCode.toString() + " - " + msg);
        this.customErrorCode = customErrorCode;
    }

    private CustomException(Integer code, String errorMessage, Throwable cause) {
        super(code.toString() + " - " + getMessage(errorMessage) + " - " + getMessage(cause), cause);
        this.code = code;
    }

    private CustomException(ErrorCode errorCode, String errorMessage, Throwable cause) {
        super(errorCode.toString() + " - " + getMessage(errorMessage) + " - " + getMessage(cause), cause);
        this.errorCode = errorCode;
    }

    private CustomException(CustomErrorCode customErrorCode, String errorMessage, Throwable cause) {
        super(customErrorCode.toString() + " - " + getMessage(errorMessage) + " - " + getMessage(cause), cause);
        this.customErrorCode = customErrorCode;
    }

    public static CustomException asCustomException(String message) {
        return new CustomException(message);
    }

    public static CustomException asCustomException(Integer errorCode, String message) {
        return new CustomException(errorCode, message);
    }

    public static CustomException asCustomException(ErrorCode errorCode, String message) {
        return new CustomException(errorCode, message);
    }

    public static CustomException asCustomException(CustomErrorCode customErrorCode, String message) {
        return new CustomException(customErrorCode, message);
    }

    public static CustomException asCustomException(Integer errorCode, String message, Throwable cause) {
        if (cause instanceof CustomException) {
            return (CustomException) cause;
        }
        return new CustomException(errorCode, message, cause);
    }

    public static CustomException asCustomException(ErrorCode errorCode, String message, Throwable cause) {
        if (cause instanceof CustomException) {
            return (CustomException) cause;
        }
        return new CustomException(errorCode, message, cause);
    }

    public static CustomException asCustomException(CustomErrorCode customErrorCode, String message, Throwable cause) {
        if (cause instanceof CustomException) {
            return (CustomException) cause;
        }
        return new CustomException(customErrorCode, message, cause);
    }

    public static CustomException asCustomException(Integer errorCode, Throwable cause) {
        if (cause instanceof CustomException) {
            return (CustomException) cause;
        }
        return new CustomException(errorCode, getMessage(cause), cause);
    }


    public static CustomException asCustomException(ErrorCode errorCode, Throwable cause) {
        if (cause instanceof CustomException) {
            return (CustomException) cause;
        }
        return new CustomException(errorCode, getMessage(cause), cause);
    }

    public static CustomException asCustomException(CustomErrorCode customErrorCode, Throwable cause) {
        if (cause instanceof CustomException) {
            return (CustomException) cause;
        }
        return new CustomException(customErrorCode, getMessage(cause), cause);
    }

    public CustomException(Throwable cause) {
        super(cause);
    }

    public CustomException(Throwable cause, ErrorCode errorCode) {
        super(cause);
        this.errorCode = errorCode;
    }

    public CustomException(String msg, Throwable cause) {
        super(msg, cause);
    }

    public CustomException(String msg, Throwable cause, ErrorCode errorCode) {
        super(msg, cause);
        this.errorCode = errorCode;
    }

    public ErrorCode geterrorCode() {
        return this.errorCode;
    }

    public void seterrorCode(ErrorCode errorCode) {
        this.errorCode = errorCode;
    }


    private static String getMessage(Object obj) {
        if (obj == null) {
            return "";
        }

        if (obj instanceof Throwable) {
            StringWriter str = new StringWriter();
            PrintWriter pw = new PrintWriter(str);
            ((Throwable) obj).printStackTrace(pw);
            return str.toString();
            // return ((Throwable) obj).getMessage();
        } else {
            return obj.toString();
        }
    }
}
